package zzzhc.image.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.table.AbstractTableModel;

public class NormalTableModel extends AbstractTableModel {
	private static final long serialVersionUID = -1233625522474507907L;

	protected Map<String, ColumnInfo> columnInfos = Collections
			.synchronizedMap(new HashMap<String, ColumnInfo>());

	protected List<String> columnOrder = new ArrayList<String>();

	protected List<Map<String, Object>> data = Collections
			.synchronizedList(new ArrayList<Map<String, Object>>());

	private static class ColumnInfo {
		@SuppressWarnings("unchecked")
		Class clazz;

		boolean editable;
	}

	public NormalTableModel() {

	}

	@SuppressWarnings("unchecked")
	public void init(String[] columnNames, Class[] classes, Boolean[] editables) {
		for (int i = 0; i < columnNames.length; i++) {
			addColumnInfo(columnNames[i], classes[i], editables[i]);
		}
	}

	public void removeAllColumns() {
		data.clear();
		columnOrder.clear();
		columnInfos.clear();
		fireTableDataChanged();
	}

	@SuppressWarnings("unchecked")
	public void addColumnInfo(String columnName, Class clazz, Boolean editable) {
		ColumnInfo columnInfo = new ColumnInfo();
		columnInfo.clazz = clazz;
		columnInfo.editable = editable;
		columnInfos.put(columnName, columnInfo);
		columnOrder.add(columnName);
	}

	public int getColumnCount() {
		return columnInfos.size();
	}

	public int getRowCount() {
		return data.size();
	}

	public boolean isCellEditable(int rowIndex, int columnIndex) {
		String columnName = getColumnName(columnIndex);
		return columnInfos.get(columnName).editable;
	}

	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		Map<String, Object> entry = data.get(rowIndex);
		entry.put(getColumnName(columnIndex), aValue);
		fireTableCellUpdated(rowIndex, columnIndex);
	}

	public Object getValueAt(int rowIndex, int columnIndex) {
		String columnName = getColumnName(columnIndex);
		return data.get(rowIndex).get(columnName);
	}

	public Class<?> getColumnClass(int columnIndex) {
		String columnName = getColumnName(columnIndex);
		return columnInfos.get(columnName).clazz;
	}

	public String getColumnName(int columnIndex) {
		return columnOrder.get(columnIndex);
	}

	public void addRow(Map<String, Object> columnData) {
		data.add(columnData);
		fireTableDataChanged();
	}

	public void removeRow(int rowIndex) {
		data.remove(rowIndex);
	}

	public void clearAll() {
		data.clear();
		fireTableDataChanged();
	}

}
